package org.person.gift.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import org.person.gift.clients.AuthClient;
import org.person.gift.constans.BaseConstants;
import org.person.gift.domain.Employee;
import org.person.gift.domain.LoginUser;
import org.person.gift.domain.Tenant;
import org.person.gift.dto.TenantRegisterDto;
import org.person.gift.exception.BusinessException;
import org.person.gift.exception.ResponseCode;
import org.person.gift.exception.SystemAssert;
import org.person.gift.mapper.EmployeeMapper;
import org.person.gift.mapper.TenantMapper;
import org.person.gift.mapper.TenantMealMapper;
import org.person.gift.query.TenantQuery;
import org.person.gift.service.IBaiduAuditService;
import org.person.gift.service.ITenantService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.person.gift.util.AjaxResult;
import org.person.gift.util.MyMailSender;
import org.person.gift.util.PageList;
import org.person.gift.util.encrypt.MD5;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author MaxPeng
 * @since 2024-01-24
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private IBaiduAuditService baiduAuditService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MyMailSender myMailSender;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private AuthClient authClient;
    @Autowired
    private TenantMealMapper tenantMealMapper;

    @Override
    @Transactional
    public void settlement(TenantRegisterDto registerDto) {
        //1.店铺信息接收，进行信息审核校验
        //校验店铺信息
        valiDateParam(registerDto);
        //2.校验完成进行存入店铺信息,状态默认为待审核
        Tenant tenant = new Tenant();
        tenant.setRegisterTime(new Date());//设置店铺入驻时间为当前时间
        //4.对店铺做审核校验，判断是否符合入驻条件，审核是自动审核+人工审核 @TODO
        //方案1：自动审核店铺内容，自动审核通过再转人工审核，审核通过店铺状态变为待激活，发送邮件通知管理员激活
        //方案2：自动审核店铺内容，审核通过修改店铺状态为待激活，然后发送邮件通知管理员，但如果多次审核未通过再转人工审核（采纳）
        //如何做自动审核？调用百度三方接口文档
        //店铺各类信息做何种类型审核
        //2）店铺电话核对
        //1）店铺名称审核
        //3）店铺地址审核
        //4）店铺logo审核
        String auditText = registerDto.getCompanyName()+" "+registerDto.getAddress();
        String imgUrl = registerDto.getLogo();
        AjaxResult auditResult = baiduAuditService.audit(auditText, imgUrl);
        //5.审核通过，就修改店铺状态为待激活，并发送激活邮件通知管理员 @TODO
        String msg="";
        if(auditResult.isSuccess()){
            tenant.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);//待激活
            //发送激活邮件
            //邮件内容
            UUID uuid =UUID.randomUUID();
            redisTemplate.opsForValue().set(tenant.getId(),uuid,30, TimeUnit.MINUTES);
            msg = "<h1>恭喜您已成功通过我们蓉礼购店铺入驻审核</h1>"+
                    "<a href='http://localhost:8081/shop/active?shopId="+tenant.getId()+"&activeCode="+uuid+"'>请点击进行激活</a>";
            myMailSender.sendMimeMessage(tenant.getAdmin().getEmail(),msg);
        }else{
            //6.如果审核未通过，就修改店铺状态未驳回，并发送邮件通知管理员重新入驻 @TODO
            tenant.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);//驳回
            //邮件内容
            msg = "您未通过蓉礼购的店铺信息审核，未通过内容如下为\\n"+auditResult.getMessage();
        }
        BeanUtils.copyProperties(registerDto,tenant);

        myMailSender.sendMimeMessage(tenant.getAdmin().getEmail(),msg);
        //3.校验店铺管理员是否存在
        Employee admin = tenant.getAdmin();
        Employee adminInDB = employeeMapper.queryByPhone(admin.getTel());
        //3.1 管理员如果在员工表格不存在，就新增管理员信息到employee表中，并且关联关系店铺和管理员信息
        if(Objects.isNull(adminInDB)){
            admin.setState(BaseConstants.Employee.STATE_WAIT_AUDIT);
            //设置盐值和密码
            String salt = UUID.randomUUID().toString();
            String password = MD5.getMD5("gift"+salt+admin.getPassword()+"123");
            LoginUser loginUser = new LoginUser();
            loginUser.setTel(admin.getTel());
            loginUser.setEmail(admin.getEmail());
            loginUser.setPassword(password);
            loginUser.setUsername(admin.getUsername());
            loginUser.setType(0);
            authClient.save(loginUser);
            if(!AjaxResult.me().isSuccess()){
                throw new BusinessException("注册失败");
            }
            admin.setLoginId(loginUser.getId());
            admin.setSalt(salt);
            admin.setPassword(password);
            employeeMapper.insert(admin);
            //若租户的管理员未注册过，注册之后将租户的adminId修改为管理员id
            tenant.setAdminId(admin.getId());
        }
        //租户信息新增
        insert(tenant);
        //3.2 管理员如果在表格中存在，解决方案：
        //1）返回错误信息，然后提示管理员登录自己账号再通过商家管理界面新增自己的店铺信息（作废，因为本系统只提供了商家入驻功能，未提供商家能在店铺管理界面新增店铺功能）
        //2）管理员存在则不需要在employee表格中新增数据，只需要关联管理员和店铺数据然后将两者的id内容存入关联数据表中即可
        //添加租户和套餐中间表
        tenantMealMapper.batchInsert(tenant.getId(),registerDto.getMealIds(),0);
    }

    @Override
    public PageList selectPageList(TenantQuery query) {
        Page<Tenant> tenantPage = new Page<>(query.getPage(), query.getRows());
        List<Tenant> list = tenantMapper.selectTenantList(tenantPage,query);
        return new PageList(tenantPage.getTotal(),list);
    }

    private void valiDateParam(TenantRegisterDto registerDto){
        List<Long> mealIds = registerDto.getMealIds();
        if(mealIds == null || mealIds.size() ==0){
            throw  new BusinessException(ResponseCode.RESPONSE_CODE_40027);
        }
        Employee admin = registerDto.getAdmin();
        SystemAssert.isEq(admin.getPassword(),admin.getConfirmPassword(),ResponseCode.RESPONSE_CODE_40011);
    }


}
